#ifndef DATA_HOLDER_H_
#define DATA_HOLDER_H_

#include <string.h>
//#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif
#include "bsplib.h"
#ifdef __cplusplus
}
#endif

//#pragma pack(1)
//#pragma anon_unions

struct Robot_firmware{
    char version[16]; //固件版本
    char time[16];  //构建时间
};

struct Robot_parameter{
 //   union{
///   char buff[64];
//    struct{   
			
			uint32_t wheel_diameter;   //轮子直径  mm
			uint32_t wheel_track;      //差分：轮距， 三全向轮：直径，四全向：前后轮距+左右轮距 mm
			uint32_t encoder_resolution;  //编码器分辨率
			uint32_t do_pid_interval;         //pid间隔 (ms)
			uint32_t kp;
			uint32_t ki;
			uint32_t kd;
			uint32_t ko;                  //pid参数比例
			uint32_t cmd_last_time;       //命令持久时间ms 超过该时间会自动停止运动
			uint32_t max_v_liner_x;
			uint32_t max_v_liner_y;
			uint32_t max_v_angular_z;
			uint32_t imu_type;//13x4 =52 byte
			uint32_t keyWords;
 //       };
//    };
};

struct Robot_velocity{
    int32_t v_liner_x; //线速度 前>0 cm/s
    int32_t v_liner_y; //差分轮 为0  cm/s
    int32_t v_angular_z; //角速度 左>0 0.01rad/s  100 means 1 rad/s
};

struct Robot_odom{
    int32_t v_liner_x;      //线速度 前>0 后<0  cm/s
    int32_t v_liner_y;      //差分轮 为0        cm/s
    int32_t v_angular_z;    //角速度 左>0 右<0  0.01rad/s   100 means 1 rad/s
    int32_t x;              //里程计坐标x       cm (这里long为4字节，下同)
    int32_t y;              //里程计坐标y       cm
    int32_t yaw;            //里程计航角        0.01rad     100 means 1 rad
};

struct Robot_pid_data{
    long input[4];  //各轮子驱动输入值
    long output[4]; //个轮子输出值
};

//#pragma pack(0)

class Data_holder{
    public:
        static Data_holder* get(){
            static Data_holder dh;
            return &dh;
        }

        void load_parameter(void);

        void save_parameter(void);
    
				void saveDefault(void);
    private:
        Data_holder(){
            strncpy((char*)&firmware_info.version, FIRMWARE_VERSION, strlen(FIRMWARE_VERSION));
            sprintf(firmware_info.time, "%s-m%de%d",FIRMWARE_TIME, 
                            MOTOR4_REVERSE<<3 | MOTOR3_REVERSE<<2 | MOTOR2_REVERSE<<1 | MOTOR1_REVERSE,
                            ENCODER4_REVERSE<<3 | ENCODER3_REVERSE<<2 | ENCODER2_REVERSE<<1 | ENCODER1_REVERSE);
            memset(&parameter, 0, sizeof(struct Robot_parameter));
            memset(&velocity, 0, sizeof(struct Robot_velocity));
            memset(&odom, 0, sizeof(struct Robot_odom));
            memset(&pid_data, 0, sizeof(struct Robot_pid_data));
            memset(imu_data, 0, sizeof(imu_data));
            }
    public:
        struct Robot_firmware  firmware_info;
        struct Robot_parameter parameter;
        struct Robot_velocity  velocity;
        struct Robot_odom      odom;
        struct Robot_pid_data  pid_data;

        float imu_data[9];
};
#endif

